package com.concurrent.sample.business.loan.service.impl;

import com.concurrent.sample.business.loan.entity.LoanEntity;
import com.concurrent.sample.business.loan.repo.LoanRepo;
import com.concurrent.sample.business.loan.service.ILoanService;
import java.util.Set;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RAtomicLong;
import org.redisson.api.RSetCache;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

@Slf4j
@Service
@RequiredArgsConstructor
public class LoanServiceImpl implements ILoanService {

  private final LoanRepo loanRepo;

  private final RedissonClient redissonClient;

  @Override
  public LoanEntity insertLoan(LoanEntity loan) {
    LoanEntity loanEntity = loanRepo.save(loan);
//    getTickerCache(loanEntity.getLoanTicketId()).add(loanEntity);
    getUsedLoanQuantity(loan.getLoanTicketId()).addAndGet(loan.getLiveQty());
    return loanEntity;
  }

  @Override
  public Set<LoanEntity> getByLoanTicketId(Long loanTicketId) {
    RSetCache<LoanEntity> tickerCache = getTickerCache(loanTicketId);
    if(tickerCache.size() != 0){
      return tickerCache.readAll();
    } else {
      Set<LoanEntity> ticketLoans = loanRepo.findByLoanTicketId(loanTicketId);
      tickerCache.addAll(ticketLoans);
      return ticketLoans;
    }
  }

  @Override
  public Long getUserLoanQuantity(Long loanTicketId) {
    // 方式一 10000 个跑完，要466秒
//    Set<LoanEntity> loanEntities = getByLoanTicketId(loanTicketId);
//    long usedQuantity = loanEntities.stream().mapToLong(LoanEntity::getLiveQty).count();
    // 方式二 10000 个跑完，要99秒
    long usedQuantity = getUsedLoanQuantity(loanTicketId).get();
    return usedQuantity;
  }

  public RSetCache<LoanEntity> getTickerCache(Long loanTicketId){
    String tickerLoanKey =  "ticket:loan:" + loanTicketId;
    return redissonClient.getSetCache(tickerLoanKey);
  }

  public RAtomicLong getUsedLoanQuantity(Long loanTicketId){
    String tickerLoanUsedLoanQuantityKey =  "ticket:loan:usedLockQuantity" + loanTicketId;
    return redissonClient.getAtomicLong(tickerLoanUsedLoanQuantityKey);
  }

}
